#!/usr/bin/env python
# -*- coding: UTF-8 -*-

import os
import shutil
import sys

execfile(os.path.join(sys.path[0], "framework.py"))

from oriolus.docker.storages.memorystorage import MemoryStorage
from oriolus.gaffer.cache import Cache
from oriolus.gaffer.gaffer.selectstrategy import LatestStrategy
from oriolus.gaffer.gaffer.catalogue import Catalogue
from oriolus.gaffer.gaffer import Gaffer, GafferError, GafferFactory
from oriolus.pith.packets.meta import Meta
from oriolus.pith.packets.packet import Packet, Status
from pmock import *
from unittest import TestCase, TestLoader, TextTestRunner

class DocketConfigurator(object):
    def __init__(self, mock_docker):
        self.__i = 0
        self.__mock_docker = mock_docker
         
    def once(self, action):
        mock = self.__mock_docker.expects(once())
        mock = action(mock)
        mock = mock.id(self.__i)
        
        if self.__i != 0:
            mock.after(self.__i - 1)
            
        self.__i += 1
        
    def at_least_once(self, action):
        mock = self.__mock_docker.expects(at_least_once())
        mock = action(mock)

class TestRemove(TestCase):
    def setUp(self):
        self.__test_packets_path = os.path.join(".", "testdata", "testpackets")

        self.__cache_path = os.path.join(".", "testdata", "gaffer_cache")
        self.__temp_dirs = (self.__cache_path,)

        self.__setup_mocks()

    def tearDown(self):
        for path in self.__temp_dirs:
            if os.path.exists(path):
                shutil.rmtree(path)
                
    def test_remove01(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_a-1.2.3.4",)
        
        self.assertRaises(GafferError, self.__gaffer.remove, packets_to_remove)
        self.__mock_docker.verify()
        
    def test_remove02(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], []), status = Status.INSTALLED))

        packets_to_remove = ("packet_a-1.2.3.4", "packet_b-2.3.4.5", "packet_c-3.4.5.6")
        
        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED)]))
        
        expected_docker_actions = ("search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED)]))",
                                   "remove(eq('packet_a-1.2.3.4'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_c-3.4.5.6'))",)

        self.assert_remove(packets_to_remove, expected_docker_actions)
        
    def test_remove03_0(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_a-1.2.3.4", "packet_b-2.3.4.5", "packet_c-3.4.5.6", "packet_d-4.5.6.7", "packet_e-5.6.7.8")
        
        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED),Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))
        
        expected_docker_actions = (
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_e')).will(return_value([Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "remove(eq('packet_c-3.4.5.6'))",
                                   "remove(eq('packet_e-5.6.7.8'))",
                                   "remove(eq('packet_d-4.5.6.7'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_a-1.2.3.4'))",
                                   )

        self.assert_remove(packets_to_remove, expected_docker_actions)

    def test_remove03_1(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_a-1.2.3.4", "packet_b-2.3.4.5", "packet_c-3.4.5.6", "packet_d-4.5.6.7", "packet_e-5.6.7.8")
        
        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED),Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))
        
        expected_docker_actions = (
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_e')).will(return_value([Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "remove(eq('packet_c-3.4.5.6'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_a-1.2.3.4'))",
                                   "remove(eq('packet_e-5.6.7.8'))",
                                   "remove(eq('packet_d-4.5.6.7'))",
                                   )

        self.assert_remove(packets_to_remove, expected_docker_actions)

    def test_remove03_2(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_c-3.4.5.6", "packet_e-5.6.7.8")
        
        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED),Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))
        
        expected_docker_actions = (
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_e')).will(return_value([Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "remove(eq('packet_c-3.4.5.6'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_a-1.2.3.4'))",
                                   "remove(eq('packet_e-5.6.7.8'))",
                                   "remove(eq('packet_d-4.5.6.7'))",
                                   )

        self.assert_remove(packets_to_remove, expected_docker_actions)

    def test_remove03_3(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_c-3.4.5.6", "packet_e-5.6.7.8")
        
        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED),Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))
        
        expected_docker_actions = (
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_e')).will(return_value([Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "remove(eq('packet_c-3.4.5.6'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_e-5.6.7.8'))",
                                   "remove(eq('packet_d-4.5.6.7'))",
                                   )

        self.assert_remove(packets_to_remove, expected_docker_actions)
    def test_remove03_4(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_c-3.4.5.6", "packet_e-5.6.7.8", "packet_a-1.2.3.4")
        
        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY),Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))
        
        expected_docker_actions = (
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_e')).will(return_value([Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "remove(eq('packet_c-3.4.5.6'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_e-5.6.7.8'))",
                                   "remove(eq('packet_d-4.5.6.7'))",
                                   "remove(eq('packet_a-1.2.3.4'))",
                                   )

        self.assert_remove(packets_to_remove, expected_docker_actions)

    def test_remove04_0(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_a-1.2.3.4", "packet_b-2.3.4.5", "packet_d-4.5.6.7", "packet_e-5.6.7.8")

        self.assertRaises(GafferError, self.__gaffer.remove, packets_to_remove)
        self.__mock_docker.verify()

    def test_remove04_1(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_a-1.2.3.4", "packet_b-2.3.4.5", "packet_d-4.5.6.7", "packet_e-5.6.7.8", "packet_c-3.4.5.6")

        self.__mock_docker.expects(at_least_once()).search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED),Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))
        expected_docker_actions = (
                                   "search(name=eq('packet_e')).will(return_value([Packet(Meta('packet_e', '5.6.7.8', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}, {'Name': 'packet_d', 'Version': '4.5.6.7'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_c')).will(return_value([Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_d')).will(return_value([Packet(Meta('packet_d', '4.5.6.7', None, [], [], [{'Name': 'packet_b', 'Version': '2.3.4.5'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.4'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.4', None, [], [], []), status=Status.INSTALLED)]))",
                                   "remove(eq('packet_e-5.6.7.8'))",
                                   "remove(eq('packet_c-3.4.5.6'))",
                                   "remove(eq('packet_d-4.5.6.7'))",
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_a-1.2.3.4'))",
                                   )

        self.assert_remove(packets_to_remove, expected_docker_actions)
        
    def test_remove05(self):
        packet_a = Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED)
        packet_c = Packet(Meta("packet_c", "3.4.5.6", None, [], [], []), status = Status.INSTALLED)
        
        packet_list = [packet_a, packet_b, packet_c]
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.4", "packet_b-2.3.4.5", "packet_c-3.4.5.6")

        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_b')).will(return_value([packet_b])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a])))
        configurer.once(lambda x: x.search(name=eq('packet_c')).will(return_value([packet_c])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a])))
        configurer.once(lambda x: x.remove(eq('packet_b-2.3.4.5'))) 
        configurer.once(lambda x: x.remove(eq('packet_c-3.4.5.6'))) 
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.4'))) 

        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove06(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b]
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.1",)

        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.1'))) 
        
        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove07(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b]
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.1", "packet_a-1.2.3.2",)

        self.assertRaises(GafferError, self.__gaffer.remove, packets_to_remove)
        self.__mock_docker.verify()

    def test_remove08(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b]
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.1", "packet_b-2.3.4.5", "packet_a-1.2.3.2",)

        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_b')).will(return_value([packet_b])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.1'))) 
        configurer.once(lambda x: x.remove(eq('packet_b-2.3.4.5'))) 
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.2'))) 

        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove09(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b]
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.1", "packet_a-1.2.3.2", "packet_b-2.3.4.5",)

        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_b')).will(return_value([packet_b])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.1'))) 
        configurer.once(lambda x: x.remove(eq('packet_b-2.3.4.5'))) 
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.2'))) 

        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove10(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status = Status.INSTALLED)
        packet_c = Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b, packet_c]
        
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.1",)

        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.1'))) 

        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove11(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status = Status.INSTALLED)
        packet_c = Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b, packet_c]
        
        self.__memory_storage.add_range(packet_list)

        packets_to_remove = ("packet_a-1.2.3.1", "packet_a-1.2.3.2", "packet_c-3.4.5.6", "packet_b-2.3.4.5",)
        
        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_c')).will(return_value([packet_c,])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_b')).will(return_value([packet_b])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.1'))) 
        configurer.once(lambda x: x.remove(eq('packet_c-3.4.5.6'))) 
        configurer.once(lambda x: x.remove(eq('packet_b-2.3.4.5'))) 
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.2'))) 

        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove12(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status = Status.INSTALLED)
        packet_c = Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b, packet_c]
        
        self.__memory_storage.add_range(packet_list)
        
        packets_to_remove = ("packet_b-2.3.4.5",)
        
        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name=eq('packet_b')).will(return_value([packet_b])))
        configurer.once(lambda x: x.search(name=eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_b-2.3.4.5')))
        
        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))
        
        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()

    def test_remove13(self):
        packet_a1 = Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED)
        packet_a2 = Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED_AS_DEPENDENCY)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status = Status.INSTALLED)
        packet_c = Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED)
        
        packet_list = [packet_a1, packet_a2, packet_b, packet_c]
        
        self.__memory_storage.add_range(packet_list)
        

        packets_to_remove = ("packet_b-2.3.4.5",)
        
        configurer = DocketConfigurator(self.__mock_docker)
        configurer.once(lambda x: x.search(name = eq('packet_b')).will(return_value([packet_b])))
        configurer.once(lambda x: x.search(name = eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.search(name = eq('packet_a')).will(return_value([packet_a1, packet_a2])))
        configurer.once(lambda x: x.remove(eq('packet_b-2.3.4.5')))
        configurer.once(lambda x: x.remove(eq('packet_a-1.2.3.2')))
        
        configurer.at_least_once(lambda x: x.search(get_all = eq(True)).will(return_value(packet_list)))

        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()
        
    def test_remove13_0(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED_AS_DEPENDENCY))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_b-2.3.4.5", "packet_a-1.2.3.2",)

        expected_docker_actions = ("search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.2'}]), status=Status.INSTALLED)]))",
                                   'search(get_all=eq(True)).will(return_value([Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY), Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status=Status.INSTALLED), Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status=Status.INSTALLED)]))',
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.2', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   'search(get_all=eq(True)).will(return_value([Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY), Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status=Status.INSTALLED), Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status=Status.INSTALLED)]))',
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.2', None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY)]))",
                                   'search(get_all=eq(True)).will(return_value([Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status=Status.INSTALLED_AS_DEPENDENCY), Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status=Status.INSTALLED), Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status=Status.INSTALLED)]))',
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_a-1.2.3.2'))",)

        self.assert_remove(packets_to_remove, expected_docker_actions)

    def test_remove13_1(self):
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status = Status.INSTALLED))
        self.__memory_storage.add(Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status = Status.INSTALLED))

        packets_to_remove = ("packet_b-2.3.4.5", "packet_a-1.2.3.2",)

        expected_docker_actions = ("search(name=eq('packet_b')).will(return_value([Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.2'}]), status=Status.INSTALLED)]))",
                                   "search(get_all=eq(True)).will(return_value([Packet(Meta('packet_a', '1.2.3.1', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_a', '1.2.3.2', None, [], [], []), status=Status.INSTALLED), Packet(Meta('packet_b', '2.3.4.5', None, [], [], [{'Name': 'packet_a', 'Version': '1.2.3.2'}]), status=Status.INSTALLED), Packet(Meta('packet_c', '3.4.5.6', None, [], [], [{'Name': 'packet_a', 'Version': '[1.2.3.1, 1.2.3.2]'}]), status=Status.INSTALLED)]))",
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.2', None, [], [], []), status=Status.INSTALLED)]))",
                                   'search(get_all=eq(True)).will(return_value([Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status=Status.INSTALLED), Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status=Status.INSTALLED)]))',
                                   "search(name=eq('packet_a')).will(return_value([Packet(Meta('packet_a', '1.2.3.2', None, [], [], []), status=Status.INSTALLED)]))",
                                   'search(get_all=eq(True)).will(return_value([Packet(Meta("packet_a", "1.2.3.1", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_a", "1.2.3.2", None, [], [], []), status=Status.INSTALLED), Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.2"}]), status=Status.INSTALLED), Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_a", "Version": "[1.2.3.1, 1.2.3.2]"}]), status=Status.INSTALLED)]))',
                                   "remove(eq('packet_b-2.3.4.5'))",
                                   "remove(eq('packet_a-1.2.3.2'))",)

        self.assert_remove(packets_to_remove, expected_docker_actions)
        
    def test_remove14(self):
        packet_a = Packet(Meta("packet_a", "1.2.3.4", None, [], [], []), status = Status.INSTALLED_AS_DEPENDENCY)
        packet_b = Packet(Meta("packet_b", "2.3.4.5", None, [], [], [{"Name": "packet_a", "Version": "1.2.3.4"}]), status = Status.INSTALLED_AS_DEPENDENCY)
        packet_c = Packet(Meta("packet_c", "3.4.5.6", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED)
        packet_d = Packet(Meta("packet_d", "4.5.6.7", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}]), status = Status.INSTALLED_AS_DEPENDENCY)
        packet_e = Packet(Meta("packet_e", "5.6.7.8", None, [], [], [{"Name": "packet_b", "Version": "2.3.4.5"}, {"Name": "packet_d", "Version": "4.5.6.7"}]), status = Status.INSTALLED)
        
        self.__memory_storage.add(packet_a)
        self.__memory_storage.add(packet_b)
        self.__memory_storage.add(packet_c)
        self.__memory_storage.add(packet_d)
        self.__memory_storage.add(packet_e)

        packets_to_remove = ("packet_c-3.4.5.6",)
        
        self.__mock_docker.expects(once()).search(name = eq('packet_c')).will(return_value([packet_c]))
        self.__mock_docker.expects(once()).search(get_all = eq(True)).will(return_value([packet_a, packet_b, packet_c, packet_d, packet_e]))
        self.__mock_docker.expects(once()).search(name = eq('packet_b')).will(return_value([packet_b]))
        self.__mock_docker.expects(once()).search(get_all = eq(True)).will(return_value([packet_a, packet_b, packet_c, packet_d, packet_e]))
        self.__mock_docker.expects(once()).remove(eq('packet_c-3.4.5.6'))

        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()
                       
    def __setup_mocks(self):
        cache = Cache(self.__cache_path)
        self.__mock_docker = Mock()
        self.__mock_trotter = Mock()
        catalogue = Catalogue(self.__mock_trotter)
        
        select_strategy = LatestStrategy()
        self.__gaffer = Gaffer(cache, self.__mock_docker, self.__mock_trotter, catalogue, select_strategy)
        
        self.__memory_storage = MemoryStorage()
        self.__mock_docker.stubs().extract_storage().will(return_value(self.__memory_storage))

        self.__mock_virtual_docker = None
        self.__original_mock_virtual_docker_install = None
        self.__exceptional_packet_path = None

    def assert_remove(self, packets_to_remove, expected_docker_actions):
        mock_docker = self.__mock_docker

        for i in range(len(expected_docker_actions)):
            action = expected_docker_actions[i]

            if i == 0:
                eval("mock_docker.expects(once()).%s.id(i)" % action)
            else:
                eval("mock_docker.expects(once()).%s.id(i).after(i-1)" % action)

        self.__gaffer.remove(packets_to_remove)
        self.__mock_docker.verify()


if __name__ == "__main__":
    suite = TestLoader().loadTestsFromTestCase(TestRemove)
    TextTestRunner(verbosity = 2).run(suite)
